package theeg.DependencyAnalysis.Core;

import LEX.Queryable;
import theeg.DependencyAnalysis.Core.DataModel.*;

import java.util.Collection;
import java.util.List;
import java.util.Set;

import static LEX.LanguageExtensions.as;

public class VerifierUtilities {

    public static boolean compareToType(DependencyDescriptor dependency, Descriptor referrer) {
        return referrer.equals(dependency.getSource().getImplementingType());
    }

    public static boolean compareToNamespace(DependencyDescriptor dependency, Descriptor referrer) {
        return referrer.equals(dependency.getSource().getImplementingType().getSubmodule());
    }

    public static boolean compareToModule(DependencyDescriptor dependency, Descriptor referrer) {
        return referrer.equals(dependency.getSource().getImplementingType().getSubmodule().getModule());
    }

    public static boolean compareToMember(DependencyDescriptor dependency, Descriptor referrer) {
        return referrer.equals(dependency.getSource());
    }

    public static List<TypeDescriptor> aggregateDependenciesToTypes(Collection<DependencyDescriptor> dependencyDescriptors, boolean b) {
        return null;
    }

    public static List<MemberDescriptor> aggregateDependenciesToMembers(Collection<DependencyDescriptor> dependencyDescriptors, boolean b) {
        return null;
    }

    public static void throwDependencyException(List<?> violations, String template) {
        StringBuilder message = new StringBuilder();
        for (Object violation : violations) {
            message.append(String.format(template, violation));
            message.append("\n");
        }
        throw new DependencyException(message.toString());
    }

    public static void selectTypes(DependencyModel dependencyModel, Descriptor referrer, Set<TypeDescriptor> sourceTypes) {

    }

    public static void selectMembers(DependencyModel model, Descriptor descriptor, Set<MemberDescriptor> exceptionMembers) {
        MemberDescriptor member = as(descriptor, MemberDescriptor.class);
        if (member != null) {
            Queryable<MemberDescriptor> query = Queryable.From(model.getDependenciesPerMember().keySet()).Where(x -> x.getIdentifier().equals(member.getIdentifier()));
            exceptionMembers.addAll(query.toList());
            return;
        }
        TypeDescriptor type = as(descriptor, TypeDescriptor.class);
        if (type != null) {
            Queryable<MemberDescriptor> query = Queryable.From(model.getDependenciesPerMember().keySet()).Where(x -> x.getImplementingType().getIdentifier().equals(type.getIdentifier()));
            exceptionMembers.addAll(query.toList());
            return;
        }
        SubmoduleDescriptor namespaceDescriptor = as(descriptor, SubmoduleDescriptor.class);
        if (namespaceDescriptor != null) {
            Queryable<MemberDescriptor> query = Queryable.From(model.getDependenciesPerMember().keySet()).Where(x -> x.getImplementingType().getSubmodule().getIdentifier().equals(namespaceDescriptor.getIdentifier()));
            exceptionMembers.addAll(query.toList());
            return;
        }
        ModuleDescriptor module = as(descriptor, ModuleDescriptor.class);
        if (module != null) {
            Queryable<MemberDescriptor> query = Queryable.From(model.getDependenciesPerMember().keySet()).Where(x -> x.getImplementingType().getSubmodule().getModule().getIdentifier().equals(module.getIdentifier()));
            exceptionMembers.addAll(query.toList());
        }
    }
}
